package fileupload

import (
	"fmt"
	"html/template"
	"net/http"
	"path/filepath"
	"strings"
	"time"

	"github.com/gin-gonic/gin"

	models "gitee.com/zinface/go.youwant-platform/database"
	"gitee.com/zinface/go.youwant-platform/external/utils"
)

func init() {
	fmt.Println(">>> fileupload/controller")
}

func oldindex(c *gin.Context) {
	fus := models.FindFileUploads()

	var items []string
	for _, fu := range fus {
		items = append(items, FileUploadUrl(&fu))
	}

	c.HTML(http.StatusOK, "fileupload_old.html", gin.H{
		"filelist": template.HTML(strings.Join(items, "\n")),
	})
}

func index(c *gin.Context) {
	c.HTML(http.StatusOK, "fileupload.html", gin.H{})
}

func failUpload(c *gin.Context, message string) {
	c.String(http.StatusInternalServerError, message)
}

func successfulUpload(c *gin.Context, message string) {
	c.String(http.StatusOK, message)
}

func upload(c *gin.Context) {
	fileHeader, err := c.FormFile("upload")
	if fileHeader == nil || err != nil {
		failUpload(c, "Not Found File")
	} else {
		uuid := models.GenerateFileUploadUUID()
		// fileExt := path.Ext(fileHeader.Filename)
		// savePath := GetSavePath(uuid + fileExt)

		// err = c.SaveUploadedFile(fileHeader, savePath)
		meta, err := fm.SaveUploadFile(c, "upload", uuid)
		if err != nil {
			failUpload(c, fmt.Sprintf("Save Upload File Failed: %v", err.Error()))
		} else {

			var saveModel = &models.FileUpload{
				FileName: meta.Name,
				FileExt:  meta.Ext,
				Uuid:     meta.UUID,
			}

			err = models.SaveFileUpload(saveModel)
			if err != nil {
				fmt.Println("保存失败..")
			}

			successfulUpload(c,
				fmt.Sprintf("Uploaded successful, %v (%v bytes)",
					uuid, fileHeader.Size))
		}
	}
}

func download(c *gin.Context) {
	fileUuid := c.Param("fileuuid")

	if fileUuid == "" {
		c.String(http.StatusBadRequest, "fileUuid is Null")
		return
	}

	file, err := models.FindFileUploadUUID(fileUuid)
	if err != nil {
		c.String(http.StatusBadRequest, err.Error())
		return
	}

	targetPath := filepath.Join(BASE_PATH, file.Uuid+file.FileExt)
	fmt.Println("准备下载:", targetPath)

	c.Header("Content-Description", "File Transfer")

	var _type string = "attachment"
	for _, preview := range pvs {
		if file.FileExt == preview && utils.GetFileSize(targetPath) < pvMaxsize {
			_type = "inline"
		}
	}
	var _param string
	_param = fmt.Sprintf("filename=%s", file.FileName)
	dispoisson := fmt.Sprintf("%s; %s", _type, _param)

	c.Header("Content-Disposition", dispoisson)
	s, err := GetFileContentTypeFromPath(targetPath)
	// c.Header("Content-Type", "application/octet-stream")
	if err == nil {
		c.Header("Content-Type", s)
	}
	c.File(targetPath)
}

func apiAll(c *gin.Context) {
	type _item_s struct {
		Id       int
		Uuid     string
		Name     string
		Ext      string
		Size     string
		CreateAt time.Time
	}

	var items = []_item_s{}

	fus := models.FindFileUploads()
	for _, fu := range fus {
		item := FileUploadItem(&fu)
		items = append(items, _item_s{
			Id:       fu.Id,
			Uuid:     fu.Uuid,
			Name:     fu.FileName,
			Ext:      fu.FileExt,
			Size:     item.Size,
			CreateAt: item.Time,
		})
	}

	c.JSON(http.StatusOK, items)
}

// apiUpload 上传文件接口
// bootstrap-fileinput 实现
func apiUpload(c *gin.Context) {
	meta, err := fm.SaveUploadFile(c, "file-data", models.GenerateFileUploadUUID())

	// 存储失败
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"error": err.Error(),
		})
		return
	}

	var saveModel = &models.FileUpload{
		FileName: meta.Name,
		FileExt:  meta.Ext,
		Uuid:     meta.UUID,
	}

	err = models.SaveFileUpload(saveModel)
	if err != nil {
		fmt.Println("保存失败..")
	}

	c.JSON(http.StatusOK, gin.H{
		"status":  http.StatusOK,
		"message": fmt.Sprintf("Uploaded successful, %v (%v bytes)", meta.Name, meta.Size),
	})
}

// apiDelete 删除文件接口
func apiDelete(c *gin.Context) {
	fileUuid := c.Param("fileuuid")
	fu, err := models.FindFileUploadUUID(fileUuid)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"status":  http.StatusInternalServerError,
			"message": err.Error(),
		})
		return
	}

	if !fm.Exists(fu.Uuid + fu.FileExt) {
		c.JSON(http.StatusInternalServerError, gin.H{
			"status":  http.StatusInternalServerError,
			"message": "File Not Exitst.",
		})
		return
	} else {
		err = fm.DeleteFile(fu.Uuid + fu.FileExt)
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{
				"status":  http.StatusInternalServerError,
				"message": err.Error(),
			})
		}
	}

	err = models.DeleteFileUpload(fu)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{
			"status":  http.StatusInternalServerError,
			"message": "File Not Exitst.",
		})
	}

	c.JSON(http.StatusOK, gin.H{
		"status":  http.StatusOK,
		"message": "File is deleted successfully.",
	})
}

// apiCleanBadFiles 清除无效文件接口
func apiCleanBadFiles(c *gin.Context) {
	var fus = models.FindFileUploads()
	var badFiles int = 0
	for _, fu := range fus {
		var localfile = fu.Uuid + fu.FileExt
		fmt.Println("检查文件错误:", fu.FileName, localfile, fm.Exists(localfile))
		if !fm.Exists(localfile) {
			models.DeleteFileUpload(&fu)
			badFiles = badFiles + 1
		}
	}
	c.JSON(http.StatusOK, gin.H{
		"status":  http.StatusOK,
		"message": fmt.Sprintf("已清除错误文件: %v 个", badFiles),
	})
}
